<?php

namespace maotool\util;

use maotool\exception\RuntimeException;

/**
 * 百分比工具类
 */
class PercentageUtil
{

    /**
     * 十分比计算
     * @param $total
     * @param $part
     * @param $precision
     * @param $model
     * @param bool $max 是否限制最大值为$cut
     * @return float|string
     */
    public static function tenPercent($total, $part, $precision = 0, $model = true, $max = false)
    {
        return self::cutCalculate($total, $part, 10, $precision, $model, $max);
    }

    /**
     * 百分比计算
     * @param $total
     * @param $part
     * @param $precision
     * @param $model
     * @param bool $max 是否限制最大值为$cut
     * @return float|string
     */
    public static function percentage($total, $part, $precision = 0, $model = true, $max = false)
    {
        return self::cutCalculate($total, $part, 100, $precision, $model, $max);
    }

    /**
     * 千分比计算
     * @param $total
     * @param $part
     * @param $precision
     * @param $model
     * @param bool $max 是否限制最大值为$cut
     * @return float|string
     */
    public static function thousandthRatio($total, $part, $precision = 0, $model = true, $max = false)
    {
        return self::cutCalculate($total, $part, 1000, $precision, $model, $max);
    }

    /**
     * 自定义分比计算
     * @param float|int $total 总量
     * @param float|int $part 部分量
     * @param int $cut 基数（如10表示十分比，100表示百分比，1000表示千分比）
     * @param int $precision 精度（小数位数）
     * @param bool $model 计算模式：true使用round()四舍五入，false使用number_format()格式化
     * @param bool $max 是否限制最大值为$cut
     * @return float|string 计算结果，根据$model参数决定返回数值型或字符串型
     */
    public static function cutCalculate($total, $part, $cut = 100, $precision = 0, $model = true, $max = false)
    {
        if ($total == 0) {
            if ($part != 0) {
                $result = $cut;
            } else {
                $result = 0;
            }
        } else {
            $result = ($part / $total) * $cut;
        }

        // 如果启用最大值限制，则不超过$cut
        if ($max && $result > $cut) {
            $result = $cut;
        }

        if ($model) {
            return round($result, $precision);
        } else {
            return number_format($result, $precision);
        }
    }

    /**
     * 计算百分比值
     *
     * @param float $value 原始值
     * @param float $percentage 百分比
     * @return float 结果值
     */
    public function calculate($value, $percentage)
    {
        return ($value * $percentage) / 100;
    }

    /**
     * 计算一个数占另一个数的百分比
     *
     * @param float $part 部分值
     * @param float $whole 总值
     * @return float 百分比
     */
    public function getPercentage($part, $whole)
    {
        if ($whole == 0) {
            throw new RuntimeException("总值不能为零");
        }
        return ($part / $whole) * 100;
    }

    /**
     * 增加百分比
     *
     * @param float $value 原始值
     * @param float $percentage 要增加的百分比
     * @return float 增加后的值
     */
    public function addPercentage($value, $percentage)
    {
        return $value + $this->calculate($value, $percentage);
    }

    /**
     * 减少百分比
     *
     * @param float $value 原始值
     * @param float $percentage 要减少的百分比
     * @return float 减少后的值
     */
    public function subtractPercentage($value, $percentage)
    {
        return $value - $this->calculate($value, $percentage);
    }

    /**
     * 格式化为百分比字符串
     *
     * @param float $value 值
     * @param int $decimals 小数位数
     * @return string 格式化后的百分比字符串
     */
    public function format($value, $decimals = 2)
    {
        return number_format($value, $decimals) . '%';
    }

}